package com.blog.blog.service.impl;

import com.blog.blog.service.AlertService;
import com.blog.blog.service.EmailNotificationService;
import com.blog.blog.service.SystemMonitorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 告警服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AlertServiceImpl implements AlertService {
    
    private final EmailNotificationService emailNotificationService;
    private final SystemMonitorService systemMonitorService;
    private final StringRedisTemplate stringRedisTemplate;
    
    @Value("${app.alert.email:admin@example.com}")
    private String alertEmail;
    
    @Value("${app.site.name:个人博客}")
    private String siteName;
    
    @Override
    @Async
    public void sendAlert(String level, String title, String message, Map<String, Object> details) {
        try {
            // 防止重复告警（相同告警5分钟内只发送一次）
            String alertKey = "alert:" + level + ":" + title.hashCode();
            String lastAlert = stringRedisTemplate.opsForValue().get(alertKey);
            if (lastAlert != null) {
                log.debug("告警已在5分钟内发送过，跳过: {}", title);
                return;
            }
            
            // 记录告警发送时间
            stringRedisTemplate.opsForValue().set(alertKey, "sent", 5, TimeUnit.MINUTES);
            
            // 构建告警邮件内容
            StringBuilder content = new StringBuilder();
            content.append("系统告警通知\n\n");
            content.append("告警级别: ").append(level).append("\n");
            content.append("告警标题: ").append(title).append("\n");
            content.append("告警时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("\n");
            content.append("告警消息: ").append(message).append("\n\n");
            
            if (details != null && !details.isEmpty()) {
                content.append("详细信息:\n");
                details.forEach((key, value) -> 
                    content.append("  ").append(key).append(": ").append(value).append("\n")
                );
            }
            
            content.append("\n请及时检查系统状态。");
            
            // 发送告警邮件
            emailNotificationService.sendSystemNotification(
                alertEmail,
                "[" + level + "] " + siteName + " - " + title,
                content.toString()
            );
            
            log.warn("系统告警已发送: [{}] {}", level, title);
            
        } catch (Exception e) {
            log.error("发送系统告警失败", e);
        }
    }
    
    @Override
    public void checkAndSendHealthAlerts() {
        try {
            Map<String, Object> health = systemMonitorService.checkHealth();
            
            // 检查内存使用
            @SuppressWarnings("unchecked")
            Map<String, Object> memoryHealth = (Map<String, Object>) health.get("memory");
            if (memoryHealth != null && !(Boolean) memoryHealth.get("healthy")) {
                double usedPercent = (Double) memoryHealth.get("usedPercent");
                sendMemoryAlert(usedPercent);
            }
            
            // 检查磁盘空间
            @SuppressWarnings("unchecked")
            Map<String, Object> diskHealth = (Map<String, Object>) health.get("disk");
            if (diskHealth != null && !(Boolean) diskHealth.get("healthy")) {
                double freePercent = (Double) diskHealth.get("freePercent");
                sendDiskSpaceAlert(freePercent);
            }
            
            // 检查数据库连接
            @SuppressWarnings("unchecked")
            Map<String, Object> dbHealth = (Map<String, Object>) health.get("database");
            if (dbHealth != null && !(Boolean) dbHealth.get("healthy")) {
                sendDatabaseAlert((String) dbHealth.get("message"));
            }
            
            // 检查Redis连接
            @SuppressWarnings("unchecked")
            Map<String, Object> redisHealth = (Map<String, Object>) health.get("redis");
            if (redisHealth != null && !(Boolean) redisHealth.get("healthy")) {
                sendRedisAlert((String) redisHealth.get("message"));
            }
            
        } catch (Exception e) {
            log.error("健康检查告警失败", e);
        }
    }
    
    @Override
    public void sendMemoryAlert(double usedPercent) {
        Map<String, Object> details = new HashMap<>();
        details.put("内存使用率", String.format("%.2f%%", usedPercent));
        details.put("阈值", "90%");
        
        String level = usedPercent > 95 ? "CRITICAL" : "WARN";
        sendAlert(level, "内存使用率过高", 
            "系统内存使用率已达到 " + String.format("%.2f%%", usedPercent) + "，请及时处理", 
            details);
    }
    
    @Override
    public void sendDiskSpaceAlert(double freePercent) {
        Map<String, Object> details = new HashMap<>();
        details.put("剩余空间", String.format("%.2f%%", freePercent));
        details.put("阈值", "10%");
        
        String level = freePercent < 5 ? "CRITICAL" : "WARN";
        sendAlert(level, "磁盘空间不足", 
            "系统磁盘剩余空间仅为 " + String.format("%.2f%%", freePercent) + "，请及时清理", 
            details);
    }
    
    @Override
    public void sendDatabaseAlert(String error) {
        Map<String, Object> details = new HashMap<>();
        details.put("错误信息", error);
        
        sendAlert("ERROR", "数据库连接异常", 
            "数据库连接出现异常，请检查数据库服务状态", 
            details);
    }
    
    @Override
    public void sendRedisAlert(String error) {
        Map<String, Object> details = new HashMap<>();
        details.put("错误信息", error);
        
        sendAlert("ERROR", "Redis连接异常", 
            "Redis连接出现异常，请检查Redis服务状态", 
            details);
    }
}
